package com.blog.service.impl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.dto.CommentDTO;
import com.blog.dto.UserInfoDTO;
import com.blog.entity.Article;
import com.blog.entity.Comment;
import com.blog.entity.Notification;
import com.blog.entity.User;
import com.blog.mapper.ArticleMapper;
import com.blog.mapper.CommentMapper;
import com.blog.mapper.UserMapper;
import com.blog.service.CommentService;
import com.blog.service.NotificationService;
import com.blog.vo.CommentVO;
import com.blog.websocket.NotificationWebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private NotificationService notificationService;

    @Override
    public List<CommentVO> getCommentsByArticleId(Long articleId) {
        // 获取一级评论
        List<Comment> rootComments = commentMapper.selectCommentsByArticleId(articleId);

        // 获取每个一级评论的回复
        for (Comment comment : rootComments) {
            List<Comment> replies = commentMapper.selectRepliesByParentId(comment.getId());
            comment.setChildren(replies);
        }

        // 转换为VO
        return rootComments.stream()
                .map(CommentVO::fromComment)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public Long addComment(CommentDTO commentDTO, Long userId) {
        // 检查文章是否存在
        Article article = articleMapper.selectById(commentDTO.getArticleId());
        if (article == null) {
            throw new RuntimeException("文章不存在");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 创建评论
        Comment comment = new Comment();
        comment.setArticleId(commentDTO.getArticleId());
        comment.setUserId(userId);
        comment.setContent(commentDTO.getContent());
        comment.setParentId(commentDTO.getParentId());
        comment.setReplyToUserId(commentDTO.getReplyToUserId());
        comment.setStatus(1); // 正常状态
        comment.setCreateTime(LocalDateTime.now());
        comment.setUpdateTime(LocalDateTime.now());

        commentMapper.insert(comment);

        // 获取文章作者
        Long authorId = article.getAuthorId();

        // 如果是回复评论，发送通知给被回复的用户
        if (commentDTO.getParentId() > 0 && commentDTO.getReplyToUserId() != null) {
            // 创建通知
            Notification replyNotification = new Notification();
            replyNotification.setUserId(commentDTO.getReplyToUserId()); // 被回复的用户
            replyNotification.setInitiatorId(userId); // 当前评论用户
            replyNotification.setType("COMMENT_REPLY");
            replyNotification.setContent(comment.getContent());
            replyNotification.setArticleId(article.getId());
            replyNotification.setCommentId(comment.getId());
            replyNotification.setStatus(0); // 未读
            replyNotification.setCreateTime(LocalDateTime.now());

            // 保存通知
            notificationService.save(replyNotification);

            // 通过WebSocket发送实时通知
            JSONObject notificationData = new JSONObject();
            notificationData.set("type", "COMMENT_REPLY");
            notificationData.set("message", user.getNickname() + "回复了你的评论");
            UserInfoDTO userInfoDTO = new UserInfoDTO();
            userInfoDTO.setAvatar(user.getAvatar());
            userInfoDTO.setNickname(user.getNickname());
            notificationData.set("fromUser", userInfoDTO);
            notificationData.set("notification", replyNotification);

            NotificationWebSocket.sendNotification(commentDTO.getReplyToUserId(), notificationData);
        }
        // 如果不是回复，而是对文章的一级评论，发送通知给文章作者
        else if (commentDTO.getParentId() == 0 && !authorId.equals(userId)) {
            // 创建通知
            Notification commentNotification = new Notification();
            commentNotification.setUserId(authorId); // 文章作者
            commentNotification.setInitiatorId(userId); // 当前评论用户
            commentNotification.setType("ARTICLE_COMMENT");
            commentNotification.setContent(comment.getContent());
            commentNotification.setArticleId(article.getId());
            commentNotification.setCommentId(comment.getId());
            commentNotification.setStatus(0); // 未读
            commentNotification.setCreateTime(LocalDateTime.now());

            // 保存通知
            notificationService.save(commentNotification);

            // 通过WebSocket发送实时通知
            JSONObject notificationData = new JSONObject();
            notificationData.set("type", "ARTICLE_COMMENT");
            UserInfoDTO userInfoDTO = new UserInfoDTO();
            userInfoDTO.setAvatar(user.getAvatar());
            userInfoDTO.setNickname(user.getNickname());
            notificationData.set("fromUser",userInfoDTO);
            notificationData.set("message", user.getNickname() + "评论了你的文章");
            notificationData.set("notification", commentNotification);

            NotificationWebSocket.sendNotification(authorId, notificationData);
        }

        return comment.getId();
    }

    @Override
    @Transactional
    public boolean deleteComment(Long commentId, Long userId) {
        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            throw new RuntimeException("评论不存在");
        }

        // 只有评论作者或管理员可以删除评论
        User user = userMapper.selectById(userId);
        if (!comment.getUserId().equals(userId) ) {
            throw new RuntimeException("无权删除该评论");
        }

        // 逻辑删除评论
        comment.setStatus(0);
        commentMapper.updateById(comment);

        // 如果是一级评论，同时删除所有回复
        if (comment.getParentId() == 0) {
            LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Comment::getParentId, commentId);

            Comment updateComment = new Comment();
            updateComment.setStatus(0);
            commentMapper.update(updateComment, wrapper);
        }

        return true;
    }

    @Override
    public Page<CommentVO> getCommentList(Integer pageNum, Integer pageSize, Integer status) {
        Page<Comment> page = new Page<>(pageNum, pageSize);

        // 构建查询条件
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        if (status != null) {
            queryWrapper.eq(Comment::getStatus, status);
        }
        queryWrapper.orderByDesc(Comment::getCreateTime);

        // 执行查询
        Page<Comment> commentPage = commentMapper.selectPage(page, queryWrapper);

        // 填充用户信息和文章信息
        List<Comment> records = commentPage.getRecords();
        for (Comment comment : records) {
            // 填充用户信息
            User user = userMapper.selectById(comment.getUserId());
            if (user != null) {
                comment.setUsername(user.getUsername());
                comment.setAvatar(user.getAvatar());
            }

            // 如果是回复评论，填充被回复用户信息
            if (comment.getReplyToUserId() != null && comment.getReplyToUserId() > 0) {
                User replyToUser = userMapper.selectById(comment.getReplyToUserId());
                if (replyToUser != null) {
                    comment.setReplyToUsername(replyToUser.getUsername());
                }
            }
        }

        // 转换为VO
        Page<CommentVO> voPage = new Page<>(pageNum, pageSize, commentPage.getTotal());
        voPage.setRecords(records.stream().map(CommentVO::fromComment).collect(Collectors.toList()));

        return voPage;
    }

    @Override
    @Transactional
    public boolean reviewComment(Long commentId, Integer status) {
        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            throw new RuntimeException("评论不存在");
        }

        // 更新评论状态
        comment.setStatus(status);
        commentMapper.updateById(comment);

        return true;
    }
}
